<template>
  <div class="app-container">
    <el-row :gutter="20">
      <el-col
        :span="6"
        :xs="24"
        style="
          border: 1px solid #ccc;
          border-radius: 4px;
          background: white;
          margin-bottom: 20px;
        "
      >
        <el-row type="flex" align="middle" style="margin: 5px 0">
          <div style="flex: 1">分类</div>
          <div>
            <el-button icon="el-icon-circle-plus-outline" circle @click="onAddCategory"></el-button>
            <el-button
              v-if="
                currentCategoryId &&
                APP_UNSET_NODE_CATEGORY_ID !== currentCategoryId
              "
              icon="el-icon-edit-outline"
              circle
              @click="onEditCategory"
            ></el-button>
            <el-button
              v-if="
                currentCategoryId &&
                APP_UNSET_NODE_CATEGORY_ID !== currentCategoryId
              "
              icon="el-icon-delete"
              circle
              @click="onDeleteCategory"
            ></el-button>
          </div>
        </el-row>
        <el-tree
          :props="defaultProps"
          :data="appCategoryData"
          :highlight-current="true"
          :indent="20"
          node-key="categoryId"
          @node-click="handleNodeClick"
          style="min-height: 500px"
        />
      </el-col>

      <el-col :span="18" :xs="24">
        <div class="searchBox">
          <el-form :inline="true" :model="search" ref="searchForm">
            <el-form-item label="应用编码：" prop="appCode">
              <el-input v-model="search.appCode" placeholder="请输入内容"></el-input>
            </el-form-item>
            <el-form-item label="应用名称：" prop="appName">
              <el-input v-model="search.appName" placeholder="请输入内容"></el-input>
            </el-form-item>
            <el-form-item style="margin-top: -2px">
              <el-button type="primary" @click="searchQuery">查询</el-button>
              <el-button
                type="info"
                @click="
                  search = {};
                  searchQuery();
                "
              >重置</el-button>
            </el-form-item>
          </el-form>
        </div>

        <qm-table
          ref="actExtAppTableRef"
          :data="query"
          keyProp="appCode,version"
          :showView="false"
          menuType="text"
          :formOptions="{ labelWidth: '120px' }"
          :rules="rules"
        >
          <qm-table-column field="appName" sortable>应用名称</qm-table-column>
          <qm-table-column field="appCode" sortable>应用编码</qm-table-column>
          <qm-table-column title="应用分类">
            <template v-slot:content="{ row }">
              {{
              row.categoryId
              | categoryNameFilter(controlData.appCategoryOptions)
              }}
            </template>
          </qm-table-column>
          <qm-table-column field="version" sortable width="100px">版本号</qm-table-column>
          <qm-table-column field="isCurrent" fieldtype="yesno" sortable width="130px">是否当前版本</qm-table-column>
          <qm-table-column field="definitionId" :renderFunc="ifDeploy" sortable width="120px">是否已部署</qm-table-column>
          <template v-slot:moreBtn="{ row }">
            <el-dropdown>
              <el-button style="padding-left: 7px" size="mini" type="text">更多</el-button>
              <el-dropdown-menu slot="dropdown">
                <el-dropdown-item @click.native="design(row)">设计流程图</el-dropdown-item>
                <el-dropdown-item @click.native="deploy(row)">部署流程图</el-dropdown-item>
                <el-dropdown-item @click.native="viewFlowPic(row)">查看流程图</el-dropdown-item>
                <el-dropdown-item @click.native="setTaskActor(row)">设置环节参与者</el-dropdown-item>
                <el-dropdown-item @click.native="downDeploy(row)">下载设计文件</el-dropdown-item>
              </el-dropdown-menu>
            </el-dropdown>
          </template>
          <template v-slot:form="{ model, viewModel }">
            <el-row>
              <el-col :span="24">
                <el-form-item label="应用分类" prop="model.categoryId">
                  <treeselect
                    v-model="model.categoryId"
                    :options="
                      handleTree(appCategoryData[0].children, 'categoryId')
                    "
                    :normalizer="normalizer"
                    :show-count="true"
                    :clearable="false"
                    placeholder="选择应用分类"
                    noChildrenText="没有了"
                  />
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="12">
                <el-form-item label="应用编码：" prop="model.appCode">
                  <el-input v-model="model.appCode"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="应用名称：" prop="model.appName">
                  <el-input v-model="model.appName"></el-input>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="12">
                <el-form-item label="版本号：" prop="model.version">
                  <el-input v-model="model.version"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="应用地址：" prop="model.appUrl">
                  <el-input v-model="model.appUrl" placeholder="待办处理时访问的页面的路由"></el-input>
                </el-form-item>
              </el-col>
            </el-row>
            <!-- <el-row>
          <el-col :span="24">
            <el-form-item label="表单地址：" prop="model.formUrl">
              <el-input
                v-model="model.formUrl"
                placeholder="自定义表单渲染页面，不清楚的留空，使用默认即可，默认是：/smartform/workflow"
              ></el-input>
            </el-form-item>
          </el-col>
            </el-row>-->
            <el-row>
              <el-col :span="24">
                <el-form-item label="表单访问前缀：" prop="model.formPrefix">
                  <el-input
                    v-model="model.formPrefix"
                    placeholder="表单访问前缀，如：/smartform、/business/demoProject等"
                  ></el-input>
                  <p
                    style="color: red"
                  >说明：该属性仅用于配置了代理类并启用工作流的自定义表单，访问前缀指的是代理类的访问前缀，即类上的@RequestMapping的值，如：/business/demoProject</p>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="12">
                <el-form-item label="表单主表名称：" prop="model.mainFrom">
                  <el-input v-model="model.mainFrom" placeholder="数据库对应完整表名"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="表单主表主键：" prop="model.mainFromKey">
                  <el-input v-model="model.mainFromKey" placeholder="表的主键名称"></el-input>
                </el-form-item>
              </el-col>
              <p style="color: red;margin-left:120px">说明：此两属性仅用于配置非自定义表单配置的工作流页面，用于撤回功能使其联动状态。</p>
            </el-row>
            <el-row>
              <el-col :span="6">
                <el-form-item label="是否启用：" prop="model.isEnabled">
                  <el-radio v-model="model.isEnabled" :label="true">是</el-radio>
                  <el-radio v-model="model.isEnabled" :label="false">否</el-radio>
                </el-form-item>
              </el-col>
              <el-col :span="6">
                <el-form-item label="当前版本：" prop="model.isCurrent">
                  <el-radio v-model="model.isCurrent" :label="true">是</el-radio>
                  <el-radio v-model="model.isCurrent" :label="false">否</el-radio>
                </el-form-item>
              </el-col>
              <el-col :span="6">
                <el-form-item label="启用正文：" prop="model.enableBodyFile">
                  <el-radio v-model="model.enableBodyFile" :label="true">是</el-radio>
                  <el-radio v-model="model.enableBodyFile" :label="false">否</el-radio>
                </el-form-item>
              </el-col>
              <el-col :span="6">
                <el-form-item label="启用附件：" prop="model.enableAttachment">
                  <el-radio v-model="model.enableAttachment" :label="true">是</el-radio>
                  <el-radio v-model="model.enableAttachment" :label="false">否</el-radio>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="24">
                <el-form-item label="描述：" prop="model.description">
                  <el-input
                    type="textarea"
                    :autosize="{ minRows: 5, maxRows: 100 }"
                    v-model="model.description"
                  ></el-input>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row v-if="viewModel.pageAction === 'view'">
              <el-col :span="12">
                <el-form-item label="创建时间：" prop="model.createdDate">
                  <el-date-picker type="datetime" v-model="model.createdDate" style="width: 100%"></el-date-picker>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="更新时间：" prop="model.updatedDate">
                  <el-date-picker type="datetime" v-model="model.updatedDate" style="width: 100%"></el-date-picker>
                </el-form-item>
              </el-col>
            </el-row>
          </template>
        </qm-table>
      </el-col>
    </el-row>

    <vxe-modal
      class="qm-workflow-process-img"
      ref="imgModal"
      v-model="imgModalVisible"
      :resize="true"
      width="900px"
      height="500px"
      title="流程图"
    >
      <img v-if="imgModalVisible" :src="processImgUrl" />
    </vxe-modal>

    <qm-uploader-modal
      ref="qmUploader"
      title="部署流程图"
      fileType=".bpmn20.xml,.bpmn"
      v-model="uploadModalVisible"
      @cancel="deployUrl = ''"
      :showUploadBtn="false"
      :url="deployUrl"
      :limit="1"
      :headers="headers"
      @file-success="
        (attach) => {
          uploadModalVisible = false;
          deployUrl = '';
          msgSuccess('部署成功');
          resetUploaderFiles();
        }
      "
    >
      <template v-slot:moreBtn>
        <el-button @click="doDeploy(true)">部署（升级）</el-button>
        <el-button @click="doDeploy(false)">部署（覆盖）</el-button>
      </template>
    </qm-uploader-modal>

    <task-actor
      v-model="taskActorModel.visible"
      v-bind="taskActorModel"
      @close="taskActorModel.visible = false"
    ></task-actor>

    <create-act-ext-app-category-modal
      v-model="createCategoryModalVisible"
      @cancel="createCategoryModalVisible = false"
      @success="onCreateCategorySuccess"
      :model="currentCategoryModel"
      :pageAction="currentCategoryPageAction"
      :loading="createCategoryModalLoading"
    ></create-act-ext-app-category-modal>
  </div>
</template>

<script>
import Controller from "@/libs/framework/controller";
import Constant from "@/libs/framework/constant";
import request from "@/utils/request";
import QmUploaderModal from "@/libs/components/qm-uploader-modal";
import { getToken, getCsrfToken } from "@/utils/auth";
import TaskActor from "./taskActor";
import CreateActExtAppCategoryModal from "./createActExtAppCategoryModal";
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";

const APP_ROOT_NODE_CATEGORY_ID = "root";
const APP_UNSET_NODE_CATEGORY_ID = "unset";
const DEFAULT_UNSET_NODE = [
  {
    categoryId: APP_UNSET_NODE_CATEGORY_ID,
    name: "未分类",
    children: [],
  },
];

export default class Instance extends Controller {
  onBeforeInit() {
    this.urls = {
      model: "/workflow/actExtApp/getEntity",
      query: [{ url: "/workflow/actExtApp/query", method: "post" }],
      save: "/workflow/actExtApp/save",
      delete: "/workflow/actExtApp/delete",
      entity: "/workflow/actExtApp/getEntity",
    };
  }

  onBeforeQuery(type, conditions, params) {
    if (type === "list") {
      params.query.categoryId = this.vm.currentCategoryId;
    }
  }

  onAfterGetEntity(res) {
    const { models, pageAction } = res;
    if (
      "create" === pageAction &&
      this.vm.currentCategoryId &&
      this.vm.currentCategoryId !== APP_UNSET_NODE_CATEGORY_ID
    ) {
      models.model.categoryId = this.vm.currentCategoryId;
    }
  }

  mixin() {
    return {
      components: {
        QmUploaderModal,
        TaskActor,
        CreateActExtAppCategoryModal,
        Treeselect,
      },
      filters: {
        categoryNameFilter(categoryId, appCategoryOptions) {
          let categoryName = "未分类";
          if (categoryId) {
            const findCategory = appCategoryOptions.find((item) => {
              return item.categoryId === categoryId;
            });
            if (findCategory) {
              categoryName = findCategory.name;
            }
          }
          return categoryName;
        },
      },
      data() {
        let csrfToken = Constant.token.csrfToken;
        let h = {};
        h[csrfToken] = getCsrfToken();
        return {
          uploadModalVisible: false,
          imgModalVisible: false,
          processImgUrl: "#",
          rules: {
            model: {
              appCode: [
                {
                  required: true,
                  message: "这是必填字段",
                  trigger: "blur",
                },
              ],
              appName: [
                {
                  required: true,
                  message: "这是必填字段",
                  trigger: "blur",
                },
              ],
              appUrl: [
                {
                  required: true,
                  message: "这是必填字段",
                },
              ],
            },
          },
          deployUrl: "",
          headers: h,
          taskActorModel: {
            visible: false,
            activitys: [],
            title: "设置环节参与者",
            actors: [],
          },
          defaultProps: {
            children: "children",
            label: "name",
          },
          currentCategoryId: undefined,
          createCategoryModalVisible: false,
          createCategoryModalLoading: false,
          currentCategoryModel: {},
          currentCategoryPageAction: "create",
          APP_UNSET_NODE_CATEGORY_ID,
          appCategoryData: [
            {
              categoryId: APP_ROOT_NODE_CATEGORY_ID,
              name: "所有分类",
              children: DEFAULT_UNSET_NODE,
            },
          ],
        };
      },
      created() {
        this.loadAppCategoryData();
      },
      methods: {
        downDeploy(data) {
          if (data) {
            window.open(
              process.env.VUE_APP_SERVER +
                "/workflow/actExtApp/getDeployXml?appCode={0}&version={1}&_r={2}".format(
                  data.appCode,
                  data.version,
                  Math.random()
                )
            );
          }
        },
        setTaskActor(data) {
          let loading = this.notifyInfo("数据加载中...");
          let url = "/workflow/actExtTaskActor/getTaskActorModel";
          request({
            url: url,
            method: "post",
            data: { definitionId: data.definitionId },
          })
            .then((vm) => {
              this.taskActorModel.activitys = vm.models.activitys;
              this.taskActorModel.actors = vm.controlData.actors;
              this.taskActorModel.visible = true;
              loading.close();
            })
            .catch((e) => {
              this.taskActorModel.visible = false;
              loading.close();
            });
        },
        viewFlowPic(data) {
          if (!data.definitionId) {
            this.$message("请先部署工作流定义文件!");
            return;
          }
          this.imgModalVisible = true;
          this.processImgUrl = `${process.env.VUE_APP_BASE_API}/workflow/actExtApp/deploymentImg?processDefinitionId=${data.definitionId}`;
        },
        design(data) {
          let url = `${
            process.env.VUE_APP_BASE_API
          }/workflow/actExtApp/design?appCode=${
            data.appCode
          }&processDefinitionId=${
            data.definitionId
          }&description=${encodeURIComponent(data.description)}&version=${
            data.version
          }&_r=${Math.random()}`;
          window.open(url);
        },
        deploy(data) {
          this.deployUrl = `${process.env.VUE_APP_BASE_API}/workflow/actExtApp/deploy?appCode=${data.appCode}&version=${data.version}`;
          this.uploadModalVisible = true;
        },
        doDeploy(override) {
          const uploader = this.$refs.qmUploader.getUploader();
          uploader.opts.query.override = override;

          (uploader.fileList || []).forEach((file) => {
            file.resume();
          });
        },
        resetUploaderFiles() {
          const uploader = this.$refs.qmUploader.getUploader();
          if (uploader) {
            uploader.cancel();
          }
          this.loadData();
        },
        loadData() {
          if (
            this.$refs["actExtAppTableRef"] &&
            this.$refs["actExtAppTableRef"].data
          ) {
            const { startIndex, pageSize } =
              this.$refs["actExtAppTableRef"].data;
            this.fetchData({
              start: (startIndex - 1) * pageSize,
              length: pageSize,
            });
          } else {
            this.fetchData();
          }
        },
        ifDeploy(d) {
          return d ? "已部署" : "未部署";
        },
        handleNodeClick(item, node, $node) {
          let categoryId = item.categoryId;
          if (APP_ROOT_NODE_CATEGORY_ID === categoryId) {
            this.currentCategoryId = undefined;
          } else if (APP_UNSET_NODE_CATEGORY_ID === categoryId) {
            this.currentCategoryId = APP_UNSET_NODE_CATEGORY_ID;
          } else {
            this.currentCategoryId = categoryId;
          }
          // 根据流程应用分类，重新加载流程应用
          this.fetchData();
        },
        onCreateCategorySuccess() {
          this.loadAppCategoryData();
          this.refresh("form");
          this.createCategoryModalVisible = false;
        },
        onAddCategory() {
          this.loadAppCategoryEntity("create");
        },
        onEditCategory() {
          this.loadAppCategoryEntity("edit");
        },
        loadAppCategoryEntity(operatePageAction) {
          this.createCategoryModalVisible = true;
          this.createCategoryModalLoading = true;
          const params = { pageAction: operatePageAction };
          if (operatePageAction === "edit" && this.currentCategoryId) {
            params.categoryId = this.currentCategoryId;
          }
          request({
            url: "/workflow/actExtAppCategory/getEntity",
            method: "post",
            params: params,
          })
            .then((res) => {
              const { pageAction, models } = res;
              const model = models.model;
              this.currentCategoryPageAction = pageAction;
              this.currentCategoryModel = model;
            })
            .catch((err) => {
              this.msgError("获取数据失败，请稍后再试");
            })
            .finally(() => {
              this.createCategoryModalLoading = false;
            });
        },
        onDeleteCategory() {
          this.$confirm("确定要删除此分类吗？", "提示", {
            confirmButtonText: "确定",
            cancelButtonText: "取消",
            type: "warning",
          })
            .then(() => {
              let loading = this.appLoading("数据提交中...");
              const deleteParams = {
                delete: JSON.stringify([
                  {
                    categoryId: this.currentCategoryId,
                  },
                ]),
              };
              request({
                url: "/workflow/actExtAppCategory/delete",
                method: "post",
                data: deleteParams,
              })
                .then((res) => {
                  const { success, message } = res;
                  if (success) {
                    this.loadAppCategoryData();
                    this.currentCategoryId = undefined;
                    this.fetchData();
                    this.msgSuccess("删除成功！");
                  } else {
                    this.msgError(message || "删除失败！");
                  }
                })
                .finally(() => {
                  loading.close();
                });
            })
            .catch(() => {});
        },
        loadAppCategoryData() {
          let loading = this.appLoading("数据加载中...");
          request({
            url: "/workflow/actExtAppCategory/getAllAppCategory",
            method: "get",
          })
            .then((appCategoryData) => {
              this.appCategoryData[0].children =
                DEFAULT_UNSET_NODE.concat(appCategoryData);
            })
            .catch(() => {
              this.msgError("获取数据失败，请稍后再试");
            })
            .finally(() => {
              loading.close();
            });
        },
        normalizer(node) {
          return {
            id: node.categoryId,
            label: node.name,
            children: node.children,
          };
        },
      },
    };
  }
}
</script>

<style scoped lang="scss"></style>
